/*	--- 使用Concurrent集合 --- 


// 我们在前面已经通过'ReentrantLock'和'Condition'实现了一个【BlockingQueue】： */
public class TaskQueue {
	private final Lock lock = new ReentrantLock();
	private final Condition condition = lock.newCondition();

	private Queue<String> task_queue = new LinkedList<>();
 
	public void addTask(String s) {
		lock.lock();

		try {
			task_queue.add(s);
			condition.signalAll();
		} finally {
			lock.unlock();
		}
	}

	public String getTask() {
		lock.lock();

		try {
			while (task_queue.isEmpty()) {
				condition.await();
			} 

			return task_queue.remove();
		} finally {
			lock.unlock();
		}
	}
}


/*
BlockingQueue的意思就是说，当'一个Thread'调用这个Queue<String> task_queue 的getTask()方法时，‘该方法内部(Queue.remove()’可能会让‘调用的线程Thread’变成'等待状态'.

直到'队列条件'满足【不为空】，线程被唤醒后，getTask()方法才会返回。


---------------------------------
因为BlockingQueue非常有用，所以我们不必自己编写，可以直接使用Java标准库的java.util.concurrent包提供的线程安全的集合：ArrayBlockingQueue。

除了BlockingQueue外，针对List、Map、Set、Deque等，java.util.concurrent包也提供了对应的‘并发集合类’。我们归纳一下： 

interface	non-thread-safe		thread-safe
List		ArrayList			CopyOnWriteArrayList
Map			HashMap				ConcurrentHashMap
Set			HashSet / TreeSet	CopyOnWriteArraySet
Queue		ArrayDeque/LinkedList	ArrayBlockingQueue / LinkedBlockingQueue
Deque		ArrayDeque/LinkedList	LinkedBlockingDeque


-------------------------

使用这些【并发集合】与使用‘非线程安全的集合类’完全相同。

我们以ConcurrentHashMap为例：  */
Map<String, String> map = new ConcurrentHashMap<>();

// 在不同的Thread中读写
map.put("A", "1");
map.put("B", "2")
map.put("A", "1");


/*
因为所有的同步和加锁的逻辑都在'集合内部'实现，对外部调用者来说，只需要正常按接口引用，其他代码和原来的非线程安全代码完全一样。

即当我们需要多线程访问时，把： */
MapString<String, String> map = new HashMap<>();

// 改为
Map<String, String> map = new ConcurrentHashMap<>();

// 就可以了


// java.util.Collections工具类还提供了一个旧的线程安全集合转换器，可以这么用：
Map unsafeMap = new HashMap();
Map threadSafeMap = Collection.synchronizedMap(unsafeMap);


/*
但是它实际上是用一个【包装类】包装了‘非线程安全的Map’，然后对所有读写方法都用synchronized加锁

但这样获得的‘线程安全集合’的性能比‘java.util.concurrent集合’要低很多，所以不推荐使用。

*/



/*---------------------------------------------

#	---- 使用Concurrent集合 の 小结 ---- 

1. 使用java.util.concurrent包提供的线程安全的并发集合可以大大简化多线程编程：

2. 多线程同时读写并发集合是安全的；

3. 尽量使用Java标准库提供的并发集合，避免自己编写同步代码。


*/























